<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>07_Reflect-Reflect设置receiver参数作用</title>
  <!-- 
  在 JavaScript 中， Reflect  是一个内置对象，提供了一些方法用于操作对象的基本操作。 Reflect  中的许多方法都可以接受一个  receiver  参数，这个参数在某些情况下非常重要，尤其是在使用  Proxy  时。
  1.  receiver  参数的基本概念
  -  receiver  参数用于指定  this  值，通常在代理对象中使用。
  - 在使用  Reflect  的方法时， receiver  参数可以影响方法的行为，特别是在访问器属性（getter 和 setter）中。

  2.  receiver  参数的作用
  receiver  参数的主要作用是在调用  Reflect  方法时，确定  this  的上下文。具体来说：

   2.1 在  get  操作中
  当你使用  Reflect.get()  方法获取对象属性时， receiver  参数可以用来确保在访问器属性中正确地绑定  this 。

  const target = {
      name: "Alice",
      get fullName() {
          return ${this.name} Smith;
      }
  };

  const handler = {
      get(target, property, receiver) {
          // 使用 receiver 确保 this 指向代理对象
          return Reflect.get(target, property, receiver);
      }
  };

  const proxy = new Proxy(target, handler);
  console.log(proxy.fullName); // 输出: Alice Smith
  在这个例子中， receiver  确保了  get fullName()  方法中的  this  指向代理对象，而不是目标对象。

   2.2 在  set  操作中
  同样地，在使用  Reflect.set()  方法设置对象属性时， receiver  参数可以帮助确保属性的赋值操作在正确的上下文中进行。

  const target = {
      name: "Alice",
      set fullName(value) {
          const [firstName, lastName] = value.split(" ");
          this.name = firstName; // this 指向目标对象
      }
  };

  const handler = {
      set(target, property, value, receiver) {
          // 使用 receiver 确保 this 指向代理对象
          return Reflect.set(target, property, value, receiver);
      }
  };

  const proxy = new Proxy(target, handler);
  proxy.fullName = "Bob Johnson"; // 设置代理对象的 fullName
  console.log(proxy.name); // 输出: Bob
  在这个例子中， receiver  确保了  set fullName()  方法中的  this  指向代理对象。

  3. 总结
  在  Reflect  的方法中设置  receiver  参数的作用主要是确保在访问器属性（getter 和 setter）中  this  的指向正确。通过使用  receiver ，可以确保在代理对象中正确地访问和修改属性，从而提高代码的灵活性和可维护性。理解  receiver  参数的作用对于在使用  Proxy  和  Reflect  时编写高效和可靠的代码非常重要。
  -->
</head>
<body>

  <script>
    const target = {
      _name: "Alice",
      set fullName(value) {
        console.log("set this:", this);
        this._name = value;
      },
      get fullName() {
        console.log("get this:", this);
        return `${this._name}`;
      }
    };

    const handler = {
      get(target, property, receiver) {
        console.log("Reflect.get: ", target, property, receiver);
        return Reflect.get(target, property, receiver);
      },
      set(target, property, value, receiver) {
        // target[key] = newValue
        // 1.好处一: 代理对象的目的: 不再直接操作原对象
        // 2.好处二: Reflect.set方法有返回Boolean值, 可以判断设置是否成功
        /*
           3.好处三:
             > receiver就是外层Proxy对象
             > Reflect.set/get最后一个参数, 可以决定对象访问器setter/getter的this指向
        */
        console.log("Reflect.set: ", target, property, value, receiver);
        return Reflect.set(target, property, value, receiver);
      }
    };

    const proxy = new Proxy(target, handler);
    proxy.fullName = "Bob Johnson"; // 设置代理对象的 fullName
    console.log(proxy.fullName); // 输出: Bob Johnson


  </script>
  
</body>
</html>